package lx.utils.http.TextRequest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import android.content.Context;
import android.text.TextUtils;

class HttpCache {

    private static final String CACHE_SUB_DIR = "HttpTextRequestCache";

    private long mCacheTime = Constants.DEFAULT_CACHE_TIME;
    private final File mCacheDirFile;

    HttpCache(String cacheDir, long cacheTime) {
        mCacheDirFile = new File(cacheDir, CACHE_SUB_DIR);
        if (cacheTime != 0) {
            mCacheTime = cacheTime;
        }
    }

    HttpCache(String cacheDir) {
        mCacheDirFile = new File(cacheDir, CACHE_SUB_DIR);
    }

    HttpCache(Context cxt, long cacheTime) {
        mCacheDirFile = new File(cxt.getCacheDir(), CACHE_SUB_DIR);
        if (cacheTime != 0) {
            mCacheTime = cacheTime;
        }
    }

    HttpCache(Context cxt) {
        mCacheDirFile = new File(cxt.getCacheDir(), CACHE_SUB_DIR);
    }

    synchronized void saveCache(String url, String data) {
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(data)) {
            return;
        }
        String name = toMd5(url);
        if (!mCacheDirFile.exists()) {
            mCacheDirFile.mkdir();
        }
        File file = new File(mCacheDirFile, name);
        if (file.exists()) {
            file.delete();
        }
        try {
            writeStringToFile(file, data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    synchronized String readCache(String url) {
        if (TextUtils.isEmpty(url)) {
            return null;
        }
        String result = null;
        String name = toMd5(url);
        File file = new File(mCacheDirFile, name);
        if (file.exists()) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - file.lastModified() > mCacheTime) {
                file.delete();
                return null;
            } else {
                try {
                    result = readFirstLineFromFile(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public long getCacheTime() {
        return mCacheTime;
    }

    public void setCacheTime(long cacheTime) {
        mCacheTime = cacheTime;
    }

    private static String toMd5(String md5Str) {
        String result = "";
        try {
            MessageDigest algorithm = MessageDigest.getInstance("MD5");
            algorithm.reset();
            algorithm.update(md5Str.getBytes("utf-8"));
            result = toHexString(algorithm.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    private static String toHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (int b : bytes) {
            if (b < 0) {
                b += 256;
            }
            if (b < 16) {
                hexString.append("0");
            }
            hexString.append(Integer.toHexString(b));
        }
        return hexString.toString();
    }

    private static void writeStringToFile(File file, String data)
            throws IOException {
        FileWriter writer = null;
        try {
            writer = new FileWriter(file);
            writer.write(data);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private static String readFirstLineFromFile(File file) throws IOException {
        if (!file.exists()) {
            return null;
        }
        String result = null;
        FileReader reader = new FileReader(file);
        BufferedReader br = new BufferedReader(reader);
        try {
            result = br.readLine();
        } finally {
            reader.close();
            br.close();
        }
        return result;
    }

}
